package com.xsystem.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;

public final class DateUtil {

	public static final String SYSTEM_TIMEZONE = "Asia/Vietnam";
	private static final String TIME_FORMAT_STR = "HH:mm";
	private static final String DATETIME_FORMAT_STR = "yyyy-MM-dd HH:mm:ss";
	private static final String DATE_TIMEZONE_FORMAT_STR = "yyyy-MM-dd HH:mm:ss z";
	private static final String DATE_TIME_FORMAT = "MMM d, yyyy h:mm:ss a";
	private static final String DATE_FORMAT_STR = "dd MMM yyyy";

	private DateUtil() {
	}

	public static String convertToDateTimeString(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(DATETIME_FORMAT_STR);
		return sdf.format(date);
	}

	public static String convertToDateTime12hString(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT);
		return sdf.format(date);
	}

	public static String convertToDateTimeString(Date date, String gmt) {
		SimpleDateFormat sdf = new SimpleDateFormat(DATETIME_FORMAT_STR);
		sdf.setTimeZone(TimeZone.getTimeZone(gmt.trim()));
		return sdf.format(date);
	}

	public static String convertToDateString(Date date, String gmt) {
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIMEZONE_FORMAT_STR);
		sdf.setTimeZone(TimeZone.getTimeZone(gmt.trim()));

		String newDate = sdf.format(date);
		return newDate.substring(0, newDate.indexOf("GMT") - 10);
	}

	public static String convertToFormalString(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_STR);
		return sdf.format(date);
	}


	public static Date convertStringToDate(String str) {
		if (str == null) {
			return null;
		}
		SimpleDateFormat sdf;

		sdf = new SimpleDateFormat(DATETIME_FORMAT_STR);

		sdf.setLenient(false);

		try {
			return sdf.parse(str);
		} catch (ParseException e) {
			return null;
		}
	}

	public static Date convertStringToDateTimezone(String str) {
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIMEZONE_FORMAT_STR);
		sdf.setLenient(false);

		try {
			return sdf.parse(str);
		} catch (ParseException e) {
			return null;
		}
	}

	public static String formatApiDateOutput(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("ddMMyy");
		return sdf.format(date);
	}

	public static Date moveDateBackwardByDayWithoutTimeChange(Date d, int numberOfDays) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(d);
		calendar.add(Calendar.DATE, Math.abs(numberOfDays) * -1);

		return calendar.getTime();
	}

	public static Date moveDateForwardByDay(Date d, int days) {
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(d);
		calendar.add(Calendar.DATE, Math.abs(days));

		return calendar.getTime();
	}

	public static long differenceInSeconds(Date start, Date end) {
		return Long.valueOf((long) Math.ceil((double) (end.getTime() - start.getTime()) / 1000));
	}

	public static int differenceInDays(Date start, Date end) {
		return (int) (Math.ceil((double) differenceInSeconds(start, end) / (60 * 60 * 24)));
	}

	public static Calendar clearTimeCalendar(Date d) {
		Calendar cal = new GregorianCalendar();
		cal.setTime(d);
		cal.set(Calendar.HOUR_OF_DAY, 0);
		cal.set(Calendar.MINUTE, 0);
		cal.set(Calendar.SECOND, 0);
		cal.set(Calendar.MILLISECOND, 0);
		return cal;
	}

	public static String getTimeAsString(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT_STR);
		sdf.setLenient(false);

		return sdf.format(date);
	}
}
